iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Cloud Native

The Journey of ASP.NET and Beyond系列 第 15

Web API Practice: Character Sheet API

  • 分享至 

  • xImage
  •  

Creating a character is a pivotal aspect of Dungeons & Dragons, as it defines the essence of the player's journey in the fantastical realms.

  今天將進行製作腳色之API,其中將重點聚焦於一對一之API開發。

角色控制區 Character Controller


  製作角色在龍與地下城中極為重要且令人興奮的一步,亦是讓玩家進入這個幻想世界的第一步,這一過程不僅定義了角色的種族和職業,還決定了角色的背景故事、技能和特殊能力。其中包含命名、確定種族、選擇職業、分配能力值、決定背景、選擇技能等等,完成這些步驟,便準備好踏上冒險之旅。以下是角色製作之API Controller,需使用者登入才可創建:

[Authorize]
[ApiController]
[Route("[controller]")]
public class CharacterController : ControllerBase
{
    private readonly CharacterService _characterService;
    public CharacterController(CharacterService characterService)
    {
        _characterService = characterService;
    }

}

製作角色 Creating a Character


  如同上面所述製作角色是龍與地下城極為重要且令人興奮的一步,若要製作角色則先製作DTO,在建Controller,再以Service新增使用者之角色,並設定AutoMapper:

// 使用者須輸入之角色資料
public class CreateCharacterDto
{
    [MaxLength(100)]
    [DefaultValue(null)]
    public string? Name { get; set; }
    [MaxLength(20)]
    [DefaultValue(null)]
    public string? Race { get; set; }
    [MaxLength(20)]
    [DefaultValue(null)]
    public string? Class { get; set; }
    [DefaultValue(null)]
    // 上傳圖片
    public IFormFile? Avatar { get; set; }
}
[HttpPost]
public async Task<IActionResult> CreateCharacter([FromForm] CreateCharacterDto createCharacter)
{
    // 以此法可由jwt抓到使用者之uuid
    var uuid = User.Claims.First(claim => claim.Type == "jti").Value;
    if (createCharacter == null)
    {
        return BadRequest("請檢察輸入資料");
    }
    var result = await _characterService.CreateCharacter(createCharacter, uuid);
    return result;
}
public async Task<IActionResult> CreateCharacter(CreateCharacterDto createCharacter, string uuid)
{
    var fullSlots = new JsonResult(new { status = "character slots are full" });
    var user = _context.UserProfile.Include(e => e.UserCharacters)
        .SingleOrDefault(e => e.Uuid.Equals(uuid));
    if (user == null) return not_found;
    // 使用者腳色數量超過3則角色槽滿
    if (user.UserCharacters.Count >= 3) return fullSlots;
    // 若角色名稱為null則以使用者名稱之角色為名
    createCharacter.Name = createCharacter.Name ?? $"{user.Username}'s character";
    var character = new UserCharacters()
    { 
        Name = createCharacter.Name,
        Uuid = uuid
    };
    character = _mapper.Map(createCharacter, character);
    _context.UserCharacters.Add(character);
    // 建立其他一對一關聯之角色資訊之資料
    var details = new CharacterDetails()
    {
        UserCharacters = character,
        Created_At = DateTime.Now,
    };
    var physical = new PhysicalCharacteristics()
    {
        UserCharacters = character,
        Created_At = DateTime.Now,
    };
    var personal = new PersonalCharacteristics()
    {
        UserCharacters = character,
        Created_At = DateTime.Now,
    };
    var notes = new CharacterNotes()
    {
        UserCharacters = character,
        Created_At = DateTime.Now,
    };
    var ability = new AbilityScores()
    {
        UserCharacters = character,
        Created_At = DateTime.Now,
    };
    _context.AddRange(details, physical, personal, notes, ability);
    try
    {
        await _context.SaveChangesAsync();
    }
    catch (Exception ex)
    {
        return fail;
    }
    return success;
}
CreateMap<CreateCharacterDto, UserCharacters>()
    .ForMember(x => x.Created_At, y => y.MapFrom(o => DateTime.Now))
    .ForMember(x => x.Name, y => y.Ignore());

能力值 Ability


  在龍與地下城中,能力值為角色在某一領域之自然天賦,能力值可以影響角色之各種屬性,例如力量、敏捷、體質、智力、感知、魅力。玩家於創建角色時會獲得一定數量之屬性點,可以用來提升能力值,能力值越高,在該領域的表現就越出色。因製作角色時能力值亦會一併建立,並給予預設值,因此在此可以直接製作獲取角色之能力值之API,先製作欲顯示之內容DTO,除能力值外尚有一調整值需考慮,是故還需製作一helper以明調整值,調整值之表,皆完成後便可製作API:

    public class GetAbilityDto
    {
        public string STR { get; set; }
        public string DEX { get; set; }
        public string CON { get; set; }
        public string INT { get; set;}
        public string WIS { get; set;}
        public string CHA { get; set;}
    }
public class ModifierHelper
{
    public string AbilityModifier(int ability)
    {
        switch (ability)
        {
            case 1:
                return $"{ability}(-5)";
            case 2 | 3:
                return $"{ability}(-4)";
            case 4 | 5:
                return $"{ability}(-3)";
            case 6 | 7:
                return $"{ability}(-2)";
            case 8 | 9:
                return $"{ability}(-1)";
            case 10 | 11:
                return $"{ability}(+0)";
            case 12 | 13:
                return $"{ability}(+1)";
            case 14 | 15:
                return $"{ability}(+2)";
            case 16 | 17:
                return $"{ability}(+3)";
            case 18 | 19:
                return $"{ability}(+4)";
            case 20 | 21:
                return $"{ability}(+5)";
            case 22 | 23:
                return $"{ability}(+6)";
            case 24 | 25:
                return $"{ability}(+7)";
            case 26 | 27:
                return $"{ability}(+8)";
            case 28 | 29:
                return $"{ability}(+9)";
            case 30:
                return $"{ability}(+10)";
        }
        return $"{ability}";
    }
}
[HttpGet("ability")]
public async Task<IActionResult> GetAbility([FromForm]string name)
{
    var uuid = User.Claims.First(claim => claim.Type == "jti").Value;
    if (name == null)
    {
        return BadRequest("請檢察輸入資料");
    }
    var result = await _characterService.GetAbility(name, uuid);
    return result;
}
public async Task<IActionResult> GetAbility(string name, string uuid)
{
    // 將以uuid找出使用者角色,並以角色表之關聯召出能力值之表
    var characters = _context.UserCharacters.Include(e => e.AbilityScores)
        .SingleOrDefault(e => e.Name.Equals(name) && e.Uuid.Equals(uuid));
    if (characters == null) return not_found;

    var ability =new GetAbilityDto()
    {
        STR = _modifierHelper.AbilityModifier(characters.AbilityScores.Strength),
        DEX = _modifierHelper.AbilityModifier(characters.AbilityScores.Dexterity),
        CON = _modifierHelper.AbilityModifier(characters.AbilityScores.Constitution),
        INT = _modifierHelper.AbilityModifier(characters.AbilityScores.Intelligence),
        WIS = _modifierHelper.AbilityModifier(characters.AbilityScores.Wisdom),
        CHA = _modifierHelper.AbilityModifier(characters.AbilityScores.Charisma)
    };
    var result = new JsonResult(new
    {
        name,
        ability
    });

    return result;
}

上一篇
Web API Practice: User Management
下一篇
Almost Swamped by The Job...
系列文
The Journey of ASP.NET and Beyond30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言